from PyQt5 import QtCore,QtGui,QtWidgets
from PyQt5.QtCore import QObject,QTimer,QRect,QPoint,QSize
from PyQt5.QtWidgets import QWidget,QSlider,QPushButton,QToolTip,QSizePolicy
from PyQt5.QtGui import QMouseEvent,QPixmap,QPainter,QCursor,QColor,QFont,QFontMetrics
from enum import Enum

class CursorPos(Enum):
    Default = 0
    Right = 1
    Left = 2
    Bottom = 3
    Top = 4
    TopRight = 5
    TopLeft = 6
    BottomRight = 7
    BottomLeft = 8

class PressWindowState(object):
    MousePressed = False
    IsPressBorder = False
    MousePos = QPoint()
    WindowPos = QPoint()
    PressedSize = QSize()


class AbsFrameLessAutoSize(QWidget):
    def __init__(self,parent=None):
        super(AbsFrameLessAutoSize, self).__init__(parent)
        self.state = PressWindowState()
        self.setMinimumSize(400,500)
        self.border = 4
        self.setMouseTracking(True)
        self.setWindowFlags(QtCore.Qt.FramelessWindowHint)
        self.setSizePolicy(QSizePolicy.Expanding,QSizePolicy.Expanding)


    def setBorder(self,border):
        self.border = border

    def mouseMoveRect(self,pos):
        if self.state.IsPressBorder:
            if pos.x() > self.width()-self.border and pos.y() < self.height() - self.border and pos.y() > self.border:
                self.setCursor(QtCore.Qt.SizeHorCursor)
                self.curPos = CursorPos.Right
            elif pos.x() < self.border and pos.y()<self.height() - self.border and pos.y() > self.border:
                self.setCursor(QtCore.Qt.SizeHorCursor)
                self.curPos = CursorPos.Left
            elif (pos.y() > self.height()-self.border and pos.x() > self.border and pos.x() < self.width()-self.border):
                self.setCursor(QtCore.Qt.SizeVerCursor);
                self.curPos = CursorPos.Bottom;
            elif (pos.y() < self.border and pos.x() > self.border and pos.x() < self.width() - self.border):
                self.setCursor(QtCore.Qt.SizeVerCursor);
                self.curPos = CursorPos.Top;
            elif (pos.y() < self.border and pos.x() > self.width() - self.border):
                self.setCursor(QtCore.Qt.SizeBDiagCursor);
                m_curPos = CursorPos.TopRight;
            elif (pos.y() < self.border and pos.x() < self.border):
                self.setCursor(QtCore.Qt.SizeFDiagCursor);
                self.curPos = CursorPos.TopLeft;
            elif (pos.x() > self.border and pos.y() > self.height() - self.border):
                self.setCursor(QtCore.Qt.SizeFDiagCursor);
                self.curPos = CursorPos.BottomRight;
            elif (pos.x() < self.border and pos.y() > self.height() - self.border):
                self.setCursor(QtCore.Qt.SizeBDiagCursor);
                m_curPos = CursorPos.BottomLeft;
            else:
                self.curPos = CursorPos.Default;
                self.setCursor(QtCore.Qt.ArrowCursor);
        else:
            if self.curPos == CursorPos.Right:
                setW = QCursor.pos().x()-self.x()
                if self.minimumWidth()<=setW and setW<=self.maximumWidth():
                    self.setGeometry(self.x(),self.y(),setW,self.height())
            elif self.curPos == CursorPos.Left:
                setW = self.x() + self.width() - QCursor.pos().x();
                setX = QCursor.pos().x();
                if (self.minimumWidth() <= setW and setW <= self.maximumWidth()):
                    self.setGeometry(setX, self.y(), setW, self.height());

            elif self.curPos == CursorPos.Bottom:
                setH = QCursor.pos().y() - self.y();
                if (self.minimumHeight() <= setH and setH <= self.maximumHeight()):
                    self.setGeometry(self.x(), self.y(), self.width(), setH);

            elif self.curPos == CursorPos.Top:
                setH = self.y() - QCursor.pos().y() + self.height();
                if (self.minimumHeight() <= setH and setH <= self.maximumHeight()):
                    self.setGeometry(self.x(), QCursor.pos().y(), self.width(), setH);

            elif self.curPos == CursorPos.TopRight:
                setH = self.y() + self.height() - QCursor.pos().y();
                setW = QCursor.pos().x() - self.x();
                setY = QCursor.pos().y();
                if (setH >= self.maximumHeight()):
                    setY = self.state.WindowPos.y() + self.state.PressedSize.height() - self.height();
                    setH = self.maximumHeight();
                if (setH <= self.minimumHeight()):
                    setY = self.state.WindowPos.y() + self.state.PressedSize.height() - self.height();
                    setH = self.minimumHeight();
                self.setGeometry(self.state.WindowPos.x(), setY, setW, setH);
            elif self.curPos == CursorPos.TopLeft:
                setY = QCursor.pos().y();
                setX = QCursor.pos().x();

                setW = pos().x() + self.width() - setX;
                setH = pos().y() + self.height() - setY;
                totalW = self.state.WindowPos.x() + self.state.PressedSize.width();
                totalH = self.state.WindowPos.y() + self.state.PressedSize.height();

                if (totalW - setX >= self.maximumWidth()):
                    setX=totalW-self.maximumWidth();
                    setW=self.maximumWidth();

                if (totalW-setX <= self.minimumWidth()):
                    setX=totalW-self.minimumWidth();
                    setW=self.minimumWidth();
                if (totalH-setY >= self.maximumHeight()):
                    setY=totalH-self.maximumHeight();
                    setH=self.maximumHeight();
                if (totalH-setY <= self.minimumHeight()):
                    setY=totalH-self.minimumHeight();
                    setH=self.minimumHeight();
                self.setGeometry(setX, setY, setW, setH);
            elif self.curPos == CursorPos.BottomRight:
                setW = QCursor.pos().x() - self.x();
                setH = QCursor.pos().y() - self.y();
                self.setGeometry(self.state.WindowPos.x(), self.state.WindowPos.y(), setW, setH);
            elif self.curPos == CursorPos.BottomLeft:
                setW = self.x() + self.width() - QCursor.pos().x();
                setH = QCursor.pos().y() - self.state.WindowPos.y();
                setX = QCursor.pos().x();
                totalW = self.state.WindowPos.x() + self.state.PressedSize.width();
                if (totalW - setX >= self.maximumWidth()):
                    setX = totalW - self.maximumWidth();
                    setW = self.maximumWidth();
                if (totalW - setX <= self.minimumWidth()):
                    setX = totalW - self.minimumWidth();
                    setW = self.minimumWidth();
                self.setGeometry(setX, self.state.WindowPos.y(), setW, setH)
    def mousePressEvent(self, a0: QtGui.QMouseEvent):
        self.state.PressedSize = self.size()
        self.state.IsPressBorder = False
        self.setFocus()
        if a0.button() == QtCore.Qt.LeftButton:
            self.state.WindowPos = self.pos()
            rect = QRect(self.border+1,self.border+1,self.width()-(self.border+1)*2,self.height()-(self.border+1)*2)
            if rect.contains(QPoint(a0.globalX(),a0.globalY())):
                self.state.MousePos = a0.globalPos()
                self.state.MousePressed = True
            else:
                self.state.IsPressBorder = True
    def mouseMoveEvent(self, a0: QtGui.QMouseEvent):
        self.mouseMoveEvent(self.mapFromGlobal(a0.globalPos()))
        if self.state.MousePressed:
            self.move(self.state.WindowPos + a0.globalPos() - self.state.MousePos)


    def mouseReleaseEvent(self, a0: QtGui.QMouseEvent):
        self.state.IsPressBorder = False
        if a0.button() == QtCore.Qt.LeftButton:
            self.state.MousePressed = False
        self.setCursor(QtCore.Qt.PointingHandCursor)






























